import { HttpClient } from '@angular/common/http';
import { Injectable, Inject } from '@angular/core';
import { Router } from '@angular/router';
import { IconDefinition } from '@ant-design/icons-angular';
import * as AllIcons from '@ant-design/icons-angular/icons';
import { ACLService } from '@delon/acl';
import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth';
import { MenuService, SettingsService, TitleService } from '@delon/theme';
import { ArrayService } from '@delon/util';
import { environment } from '@env/environment';
import { NzIconService } from 'ng-zorro-antd/icon';
import { Observable, zip, catchError, map } from 'rxjs';
import { DeptService } from '../../routes/system/dept/dept.service';
import { AuthDictService } from '../../routes/system/dict/service/dict.service';

const antDesignIcons = AllIcons as {
  [key: string]: IconDefinition;
};
const icons: IconDefinition[] = Object.keys(antDesignIcons).map(key => antDesignIcons[key]);

/**
 * Used for application startup
 * Generally used to get the basic data of the application, like: Menu Data, User Data, etc.
 */
@Injectable()
export class StartupService {
  constructor(
    iconSrv: NzIconService,
    private menuService: MenuService,
    private settingService: SettingsService,
    private aclService: ACLService,
    private titleService: TitleService,
    @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService,
    private httpClient: HttpClient,
    private router: Router,
    private arrayService: ArrayService,
		private deptService: DeptService,
		private dictService: AuthDictService
  ) {
    iconSrv.addIcon(...icons);
    iconSrv.fetchFromIconfont({
      scriptUrl: './assets/js/iconfont.js'
    });
  }

  getAreaId() {
    return new Observable(x => {
      let data = '';
      this.httpClient
        .get('common-serve/area-settings/getAreaId')
        .toPromise()
        .then((res: any) => {
          if (res) {
            data = res;
          }
        })
        .catch(e => {})
        .finally(() => {
          x.next(data);
        });
    });
  }

  load(): Observable<void> {
    return zip(
      this.httpClient.get('blade-user/info'),
      this.httpClient.get(`blade-system/menu/routes?subsystemId=${environment.subsystem.id}`),
			this.httpClient.get('blade-system/menu/buttons?subsystemId=' + environment.subsystem.id),
      this.getAreaId(),
			this.getMainLocationList(),
			this.getLocationList(),
			this.getUserList()
      // this.getCorpCargoList(),
      // this.getShipAgentList()
    ).pipe(
      // @ts-ignore
      catchError(() => {
        this.tokenService.clear();
        this.router.navigateByUrl(this.tokenService.login_url!);
        return null;
      }),

      map(([info, router,buttons , area]: any[]) => {
        info.areaId = area;
        this.settingService.setUser(info);

				this.deptService
					.getUserDeptBiz({
						subsystemCode: 'tally',
						code: 'tally',
					})
					.subscribe((res) => {
						this.dictService.tallyUserList = res.filter(i => i.id !== -1);
					});
        // 应用信息：包括站点名、描述、年份
        // this.settingService.setApp(appData.app);
        // 用户信息：包括姓名、头像、邮箱地址
				const aclData = this.convertToAclData(buttons);
				this.aclService.setAbility(aclData);
        // // 初始化菜单
        const menuData = this.convertToMenu(router);
        this.menuService.add(menuData);
      })
    );
  }

  convertToMenu(data: any) {
    this.arrayService.visitTree(data, item => {
      item.text = item.name;
      item.link = item.path;
      item.isLeaf = !item.hasOwnProperty('children') || item.children.length === 0;
    });
    return data;
  }

	convertToAclData(data: any): any {
		const arr = [];
		data.forEach(res => {
			arr.push(res.code);
		});
		return arr;
	}

	getMainLocationList(): any {
		return new Observable((x) => {
			const data = '';
			this.httpClient
				.get('common-serve/area-settings/pageAreaSettings?size=999&current=1')
				.toPromise()
				.then((res: any) => {
					const locationInfo = {};
					res.records.forEach((i) => {
						locationInfo[i.id] = i.name;
					});
					this.dictService.dictMainLocationInfo = locationInfo;
					this.dictService.dictMainLocationInfoList = res.records;
				})
				.catch((e) => {})
				.finally(() => {
					x.next(data);
				});
		});
	}

	getLocationList(): any {
		return new Observable((x) => {
			const data = '';
			this.httpClient
				.get('common-serve/cargo-location-info/list')
				.toPromise()
				.then((res: any) => {
					const locationInfo = {};
					res.forEach((i) => {
						locationInfo[i.id] = i.name;
					});
					const locationInfoList = res
						.filter((i) => i.parentId === '0')
						.sort((a, b) => {
							return a.id - b.id;
						});

					this.dictService.dictLocationInfo = locationInfo;
					this.dictService.dictLocationInfoList = locationInfoList;
				})
				.catch((e) => {})
				.finally(() => {
					x.next(data);
				});
		});
	}

	getUserList(): any {
		return new Observable((x) => {
			const data = '';
			this.deptService
				.getUserDeptBiz({code: 'tally', subsystemCode: 'tally'})
				.toPromise()
				.then((res: any) => {
					this.dictService.tallyUserList = res.filter(i => i.id !== -1);
				})
				.catch((e) => {})
				.finally(() => {
					x.next(data);
				});
		});
	}
}
